<!--
 * @Description:  弹框
 * @Author: 2712638312@qq.com
 * @Date: 2022-04-29 01:06:15
 * @LastEditors: Mr.wangxf 2712638312@qq.com
 * @LastEditTime: 2023-11-01 19:40:06
 -->

<template>
  <teleport to="#cdb-dialog-target">
    <transition
      name="custom-classes-transition"
      enter-active-class="animate__animated animate__faster animate__fadeIn"
      leave-active-class="animate__animated animate__faster animate__fadeOut"
    >
      <section
        class="flex fixed w-100 h-100"
        v-if="dialogVisible"
        :style="`z-index:${zindex};`"
      >
        <section
          v-if="model.modal"
          class="w-100 h-100 absolute xr-dialog-target-box"
          @click.stop.prevent="beforeClose('modalClose')"
        ></section>

        <section
          class="kxt-dialog-tmp-box animate__animated"
          :class="
            model.contentClass + ' ' + dialogVisible
              ? model.inAnimate
              : model.outAnimate
          "
          :style="`${model.contentStyle};--animate-duration: 0.2s;`"
          v-my-drag="{
            dragList: propsValue.dragList
              ? ['kxt-dialog-tmp-header', 'kxt-dialog-tmp-header-title']
              : ['wwwwwwwwwww'],
          }"
        >
          <section
            class="w-100 kxt-dialog-tmp-header flex-between-center"
            :style="propsValue.dragList ? 'cursor: move;' : ''"
          >
            <span
              class="kxt-dialog-tmp-header-title"
              v-html="model.title"
            ></span>
            <el-icon
              class="kxt-dialog-tmp-header-clear"
              @click.stop.prevent="beforeClose('beforeClose')"
            >
              <close />
            </el-icon>
          </section>
          <section
            class="w-100"
            :class="
              propsValue.unScrollAuto ? 'overflow_auto ' : 'overflow_hidden'
            "
            :style="`height: calc(100% - ${
              model.showFooter ? 48 + Number(model.footerHeight) : 48
            }px); ${model.centerStyle}`"
            ref="dialogRef"
            @scroll="onScroll"
          >
            <slot name="body"></slot>
          </section>
          <section
            :style="`height:${model.footerHeight}px;`"
            class="w-100 kxt-dialog-tmp-footer flex"
            v-if="model.showFooter"
          >
            <slot name="footer">
              <div class="button-center">
                <el-button
                  :disabled="cantConfirm"
                  type="primary"
                  round
                  @click="confirm"
                  >{{ model.confirmText }}</el-button
                >
              </div>
            </slot>
          </section>
        </section>
      </section>
    </transition>
  </teleport>
</template>

<script lang="ts" setup>
import { type Ref, ref, reactive, nextTick, watch, onBeforeUnmount } from "vue";
/* eslint-disable */
import { Close } from "@element-plus/icons-vue";
/* eslint-enable */
import { _getPageMaxZIndex, _dragFun } from "./../utils/utils";
import { useZIndex } from "element-plus";

interface XkdDialog_PropsParams {
  modelValue: boolean; // model
  title?: string; // 名称
  showFooter?: boolean; // 是否显示底部
  contentClass?: string; // 盒子 class
  contentStyle?: string; // 盒子 style
  footerHeight?: number | string; // 底部高度
  centerStyle?: string; //盒子内容 style
  unScroll?: boolean; // 是否自动动底部
  unScrollAuto?: boolean; // 是否可以滚动
  checkCancel?: boolean | undefined; // 是否执行关闭
  closeOnClickModal?: boolean | undefined; //是否点击 modal 关闭
  modal?: boolean | undefined; //是否遮罩层
  inAnimate?: string; //初始动画
  outAnimate?: string; //结束动画
  // zindex?: number //层级
  confirmText?: string; //按钮文字
  cantConfirm?: boolean;
  dragList?: boolean; // 拖拽列表
}

/**
 * @name: 2712638312@qq.com
 * @desc: 默认赋值 props
 */
const propsValue = withDefaults(defineProps<XkdDialog_PropsParams>(), {
  showFooter: false,
  title: "提示",
  contentClass: "",
  contentStyle: "",
  footerHeight: 48,
  centerStyle: "",
  unScroll: true,
  unScrollAuto: true,
  checkCancel: true,
  closeOnClickModal: true,
  modal: true,
  modelValue: false,
  inAnimate: "animate__zoomIn",
  outAnimate: "animate__zoomOut",
  // zindex: 0,
  confirmText: "确定", //按钮文字
  dragList: true,
});

const dialogVisible: Ref<boolean> = ref(propsValue.modelValue);

// 监听 dialog 参数
const newPropsValue = reactive<XkdDialog_PropsParams>(propsValue);
const model: any = ref({});
const resloveProp = (data: any): XkdDialog_PropsParams => {
  const res: any = {};
  for (const key in data) {
    if (Object.prototype.hasOwnProperty.call(data, key)) {
      res[key] = data[key];
    }
  }
  return res;
};
model.value = resloveProp(newPropsValue);
// 动态获取层级
// const zindex: any = ref(newPropsValue.zindex)
const zindex = useZIndex().nextZIndex();
const dialogRef: Ref<any> = ref(null);

/**
 * 2712638312@qq.com
 * @description: 拖拽
 * @param {*}
 */
const vMyDrag = {
  mounted: (el: HTMLElement, binding: any, vnode: any): void => {
    return _dragFun(el, binding, vnode);
  },
};

/**
 * @name: 2712638312@qq.com
 * @desc: propsValue
 */
watch(
  () => propsValue,
  (count) => {
    const _modelNew: XkdDialog_PropsParams = resloveProp(count);
    const _resetModel: XkdDialog_PropsParams = { ...model.value, ..._modelNew };

    model.value = _resetModel;
    dialogVisible.value = _resetModel.modelValue;

    // zindex.value = zindex.value || _getPageMaxZIndex()
    const mo = (e: any) => {
      e.preventDefault();
    };
    if (!_resetModel.modelValue) {
      document.body.style.overflow = "";
      document.removeEventListener("touchmove", mo, false);
    } else {
      document.body.style.overflow = "hidden";
      document.removeEventListener("touchmove", mo, false);
      nextTick(() => {
        let t: any = null;
        clearTimeout(t);
        t = setTimeout(() => {
          clearTimeout(t);
          setScrollTop();
        }, 300);
      });
    }
  },
  { deep: true }
);

const onScroll = (value: any): void => {
  emit("onScroll", value);
};

/**
 * @name: 2712638312@qq.com
 * @desc: 滚动最底部
 */
const setScrollTop = (event = false): void => {
  if (propsValue.unScroll) {
    nextTick(() => {
      let timer: any = null;
      let scrollTop: number = !event ? 0 : dialogRef.value.scrollTop;
      cancelAnimationFrame(timer);
      timer = requestAnimationFrame(function fn() {
        if (dialogRef.value?.scrollHeight) {
          if (scrollTop < dialogRef.value.scrollHeight) {
            if (!event) {
              scrollTop +=
                scrollTop + (dialogRef.value.scrollHeight - scrollTop) / 10;
            } else {
              scrollTop += 50;
            }
            dialogRef.value.scrollTop = scrollTop;
            timer = requestAnimationFrame(fn);
          } else {
            dialogRef.value.scrollTop = dialogRef.value.scrollHeight;
            cancelAnimationFrame(timer);
          }
        } else {
          cancelAnimationFrame(timer);
        }
      });
    });
  }
};

/**
 * @name: 2712638312@qq.com
 * @desc: emit 回调事件定义
 */
const emit = defineEmits<{
  /* eslint-disable */
  (e: "confirmClick", data: object): void;
  (e: "update:modelValue", data: boolean): void;
  (e: "cancelClick", data: object): void;
  (e: "completeClick", data: any): void;
  (e: "onScroll", data: any): void;
  /* eslint-enable */
}>();

/**
 * @name: 2712638312@qq.com
 * @desc: 取消
 */
const beforeClose = (event: string): void | undefined | boolean => {
  if (event == "modalClose" && !model.value.closeOnClickModal) {
    return false;
  }
  if (model.value.checkCancel) {
    cancel();
  }
  emit("cancelClick", model.value);
  emit("completeClick", { event, model: model.value });
};

/**
 * @name: 2712638312@qq.com
 * @desc: 确认
 */
const confirm = (): void => {
  if (model.value.checkCancel) {
    cancel();
  }
  emit("confirmClick", model.value);
  emit("completeClick", { event: "confirm", model: model.value });
};

/**
 * @author: 2712638312@qq.com
 * @description: 完成
 */
const cancel = (): void => {
  dialogVisible.value = false;
  emit("update:modelValue", dialogVisible.value);
};

// onBeforeUnmount(() => {
//   console.log('卸载销毁后')
// })

/**
 * @name: 2712638312@qq.com
 * @desc: 导出组件
 */
defineExpose({
  confirm,
  beforeClose,
  setScrollTop,
  dialogRef,
  model: model.value,
});
</script>
<style lang="scss" scoped>
@import "./style.scss";
.w-100 {
  width: 100% !important;
}
.h-100 {
  height: 100% !important;
}
.xr-dialog-target-box {
  background: rgba(0, 0, 0, 0.6);
  z-index: -1;
}

/*
 * @Description: 
 * @version: 
 * @Author: 2712638312@qq.com
 * @Date: 2022-04-29 01:06:21
 * @LastEditors: Mr.wangxf 2712638312@qq.com
 * @LastEditTime: 2023-10-14 16:25:23
 */

.kxt-dialog-tmp-box {
  width: 800px;
  height: 540px;
  background: #ffffff;
  box-shadow: 0px 12px 42px 0px rgba(38, 38, 38, 0.24);
  border-radius: 14px;
  overflow: hidden;

  .kxt-dialog-tmp-header {
    height: 48px;
    border-radius: 14px 14px 0px 0px;
    background: #fff;
    padding: 0px 24px;
    border-bottom: 1px solid #f0f0f0;
    .kxt-dialog-tmp-header-title {
      font-size: 16px;
      font-weight: 400;
      // color: $xkd-color-black;
    }
    .kxt-dialog-tmp-header-clear {
      // height: 28px;
      // width: 28px;
      cursor: pointer;
      cursor: hand;
      font-size: 20px;
      &:hover {
        border-radius: 50%;
        animation: rotateClose 0.45s ease 0.5;
        animation-fill-mode: forwards;
      }
    }
  }

  .kxt-dialog-tmp-footer {
    border-radius: 0px 0px 14px 14px;
    background: #fff;
    padding: 0px 24px;
  }
}
</style>
